<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            overflow: hidden;
        }
    </style>
</head>

<body>
    <canvas id="canvas"></canvas>
</body>
<script id="ColorVertexShader" type="x-shader/x-vertex">
    attribute vec4 a_Position;
    uniform float u_PointSize;
    uniform mat4 u_ModelM4;
    uniform mat4 u_PvM4;
    void main(){
        gl_Position = u_PvM4 * u_ModelM4 * a_Position;
        gl_PointSize = u_PointSize;
    }
</script>
<script id="ColorFragmentShader" type="x-shader/x-fragment">
    precision mediump float;
    uniform vec4 u_Color;
    void main(){
        gl_FragColor = u_Color;
    }
</script>
<script type="module">
    import { Matrix4, Vector3, Color, OrthographicCamera, PerspectiveCamera, Spherical } from '../js/three.module.js';
    import { CreateProgram, imgPromise } from '../js/Utils.js';
    import lib from '../js/ThreeLib.js';
    import CameraController from '../js/CameraController.js'
    import Poly from '../js/Poly4.js'
    import Control from '../js/Control.js'
    import Square from '../js/objs/Square.js'

    import Geo from '../js/Poly2/Geo.js'
    import Mat from '../js/Poly2/Mat.js'
    import Obj3D from '../js/Poly2/Obj3D.js'
    import Scene from '../js/Poly2/Scene.js'



    //#region gl
    const canvas = document.getElementById("canvas");
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;

    const gl = canvas.getContext("webgl", { antialias: true, });

    gl.enable(gl.BLEND);
    gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
    gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);//去图片描边
    gl.enable(gl.DEPTH_TEST);
    //#endregion

    const scene = new Scene({ gl: gl });
    scene.addAxisProgram();
    scene.regProgram('color', {
        program: CreateProgram(gl,
            document.querySelector('#ColorVertexShader').innerText,
            document.querySelector('#ColorFragmentShader').innerText),
        attribs: ['a_Position'],
        uniforms: ['u_PvM4', 'u_ModelM4', 'u_PointSize', 'u_Color']
    })


    const pvM4 = new Matrix4();
    const modelM4 = new Matrix4();
    const eye = new Vector3(2, 2, 2);
    const lookAt = new Vector3();

    const camera = new PerspectiveCamera(45, canvas.width / canvas.height, 1, 20);
    const cameraController = new CameraController({
        canvas,
        camera,
        pvMatrix: pvM4,
        eye,
        lookAt,
    });


    const axis = new Obj3D().createAxis('axis');
    scene.add(axis);

    const a1 = new Vector3(1, 0, 0.9);
    const a2 = new Vector3();
    const b1 = new Vector3(1, 0, 0);
    const b2 = new Vector3(0, 0, 1);

    scene.add(createLine(a1, a2));
    scene.add(createLine(b1, b2))

    function lineIntersect(p0, p1, p2, p3) {
        var A1 = p1.z - p0.z,
            B1 = p0.x - p1.x,
            C1 = A1 * p0.x + B1 * p0.z,
            A2 = p3.z - p2.z,
            B2 = p2.x - p3.x,
            C2 = A2 * p2.x + B2 * p2.z,
            denominator = A1 * B2 - A2 * B1;

        return {
            x: (B2 * C1 - B1 * C2) / denominator,
            y: (A1 * C2 - A2 * C1) / denominator
        }
    }

    const node = lineIntersect(a1, a2, b1, b2);
    console.log(node)
    scene.add(createNode(new Vector3(node.x, 0, node.y)))


    function createNode(node) {
        return new Obj3D({
            geo: new Geo({
                data: {
                    'a_Position': { size: 3, array: new Float32Array([...node]) },
                },
            }),
            mat: new Mat({
                program: 'color',
                mode: ['POINTS'],
                data: {
                    'u_PvM4': { type: 'uniformMatrix4fv', value: pvM4.elements },
                    'u_ModelM4': { type: 'uniformMatrix4fv', value: modelM4.elements },
                    'u_PointSize': { type: 'uniform1f', value: 30 },
                    'u_Color': { type: 'uniform4fv', value: [Math.random(), Math.random(), Math.random(), 1] },
                },
            }),
        });
    }
    function createLine(node, node1) {
        return new Obj3D({
            geo: new Geo({
                data: {
                    'a_Position': { size: 3, array: new Float32Array([...node, ...node1]) },
                },
            }),
            mat: new Mat({
                program: 'color',
                mode: ['LINES', 'POINTS'],
                data: {
                    'u_PvM4': { type: 'uniformMatrix4fv', value: pvM4.elements },
                    'u_ModelM4': { type: 'uniformMatrix4fv', value: modelM4.elements },
                    'u_PointSize': { type: 'uniform1f', value: 30 },
                    'u_Color': { type: 'uniform4fv', value: [Math.random(), Math.random(), Math.random(), 1] },
                },
            }),
        });
    }


    (function ani() {
        draw();
        requestAnimationFrame(ani)
    })();


    function draw() {
        scene.setUniform('u_PvM4', { value: pvM4.elements });
        scene.draw();
    }
</script>

</html>